using Microsoft.Office.Interop.Outlook;
using PeDALS.Tools.AZ.PSTArchive.OutputData;
//using PeDALS.Tools.AZ.PSTArchive.TransformData;
using System;
using System.Collections;                   //***???
using System.Collections.Generic;
using System.Collections.Specialized;       //***???
using System.ComponentModel;
using System.Diagnostics;
using System.IO;                            //***???
using System.IO.IsolatedStorage;            //***???
using System.Reflection;
using System.Text;
using System.Threading;
using System.Xml.Serialization;

namespace PeDALS.Tools.AZ.PSTArchive.OutlookEngine
{
    public partial class Extract : Component, iPlug
    {
        /////////////////////////////////////////////////////////////
        #region Private variables

        //private const string PR_ATTACH_DATA_BIN = "http://schemas.microsoft.com/mapi/proptag/0x37010102";
        private const string PR_ATTACH_EXTENSION = "http://schemas.microsoft.com/mapi/proptag/0x3703001E";
        private const string PR_ATTACH_MIME_TAG = "http://schemas.microsoft.com/mapi/proptag/0x370E001E";
        private const string PR_CREATION_TIME = "http://schemas.microsoft.com/mapi/proptag/0x30070040";
        private const string PR_LAST_MODIFICATION_TIME = "http://schemas.microsoft.com/mapi/proptag/0x30080040";
        private const string PR_TRANSPORT_MESSAGE_HEADERS = "http://schemas.microsoft.com/mapi/proptag/0x007D001E";
        private bool mblnNewExport;
        private bool mblnWriteAttachmentBinary;
        private bool mblnWriteMessageBinary;
        private Stopwatch mswTime = new Stopwatch();
        private System.Timers.Timer mtTimer = new System.Timers.Timer(60000);

        //private DateTime mdtStart;

        private int mintItemsProcessed;
        private int mintItemsCount;
        private int mintTaskItemsProcessed;
        private int mintTaskItemsCount;
        private int mintMessagesExported;
        private int mintFoldersExported;

        //private int mintFoldersExported;
        //private int mintFoldersProcessed;

        private string mstrCurrentOperation;
        private string mstrExportFolder;
        private string mstrPSTFilename;

        private MAPIFolder molRootFolder;
        private NameSpace molNamespace;

        private delegate void WorkerEventHandler(MAPIFolder olFolder, AsyncOperation aoOperation);

        private SendOrPostCallback onStart;
        private SendOrPostCallback onProgress;
        private SendOrPostCallback onComplete;
        private SendOrPostCallback onException;

        private HybridDictionary mhdStateDictionary =
            new HybridDictionary();

        #endregion

        /////////////////////////////////////////////////////////////
        #region Public properties

        #region iPlug Properties

        #region Metadata

        /// <summary>
        /// The name of the plug-in.
        /// </summary>
        public string Name
        {
            get
            {
                return Assembly.GetExecutingAssembly().GetName().Name;
            }
        }
        /// <summary>
        /// The description of the plug-in.
        /// </summary>
        public string Description
        {
            get
            {
                return string.Format("{0} - {1}", FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).Comments, Version);
            }
        }
        /// <summary>
        /// Boolean to indicate if a profile definition is required for the plug-in.
        /// </summary>
        public bool ProfileRequired
        {
            get
            {
                return true;
            }
        }
        /// <summary>
        /// The default PST profile for the plug-in.
        /// </summary>
        public string DefaultProfile
        {
            get
            {
                return "";
            }
        }
        /// <summary>
        /// The version of the plug-in.
        /// </summary>
        public string Version
        {
            get
            {
                return string.Format("v. {0} {1}", FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion, FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion);
            }
        }
        /// <summary>
        /// The author of the plug-in.
        /// </summary>
        public string Author
        {
            get
            {
                return string.Format("{0}", FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).CompanyName);
            }
        }

        #endregion Metadata

        #endregion iPlug Properties

        #endregion

        /////////////////////////////////////////////////////////////
        #region Public events

        #region iPlug Events
        public event ExecutionProgressEventHandler ExecutionProgress;
        public event ExecutionCompleteEventHandler ExecutionComplete;
        public event ExecutionExceptionEventHandler ExecutionException;
        #endregion iPlug Events

        #endregion

        /////////////////////////////////////////////////////////////
        #region Construction

        public Extract()
        {
            InitializeComponent();
            InitializeDelegates();
        }

        public Extract(IContainer icContainer)
        {
            icContainer.Add(this);

            InitializeComponent();
            InitializeDelegates();
        }

        protected virtual void InitializeDelegates()
        {
            onProgress =
                new SendOrPostCallback(PostProgress);
            onComplete =
                new SendOrPostCallback(PostComplete);
            onException =
                new SendOrPostCallback(PostException);
        }

        #endregion Construction

        /////////////////////////////////////////////////////////////
        #region Internal events

        // This method is invoked via the AsyncOperation object,
        // so it is guaranteed to be executed on the correct thread.
        private void PostProgress(object oState)
        {
            ProgressEventArgs peaArgs =
                oState as ProgressEventArgs;

            OnExecutionProgress(peaArgs);
        }

        protected virtual void OnExecutionProgress(ProgressEventArgs peaArgs)
        {
            if (ExecutionProgress != null)
            {
                ExecutionProgress(this, peaArgs);
            }
        }

        // This method is invoked via the AsyncOperation object,
        // so it is guaranteed to be executed on the correct thread.
        private void PostComplete(object oState)
        {
            CompleteEventArgs ceaArgs =
                oState as CompleteEventArgs;

            OnExecutionComplete(ceaArgs);
        }

        protected virtual void OnExecutionComplete(CompleteEventArgs ceaArgs)
        {
            if (ExecutionComplete != null)
            {
                ExecutionComplete(this, ceaArgs);
            }
        }

        // This method is invoked via the AsyncOperation object,
        // so it is guaranteed to be executed on the correct thread.
        private void PostException(object oState)
        {
            ProgressEventArgs peaArgs =
                oState as ProgressEventArgs;

            OnExecutionException(peaArgs);
        }

        protected virtual void OnExecutionException(ProgressEventArgs peaArgs)
        {
            if (ExecutionException != null)
            {
                ExecutionException(this, peaArgs);
            }
        }

        #endregion

        /////////////////////////////////////////////////////////////
        #region Public Methods

        #region iPlug Methods

        /// <summary>
        /// Executes the plug-in.
        /// </summary>
        /// <returns>void</returns>
        public void Execute(string strPSTFilename, string strExportFolder, string strProfile, bool blnWriteMessageBinary, bool blnWriteAttachmentBinary)
        {
            mswTime.Reset();
            mswTime.Start();
            mintTaskItemsProcessed = 0;
            mintTaskItemsCount = 1;
            mintItemsProcessed = 0;
            mintItemsCount = 10000;
            mintMessagesExported = 0;
            mintFoldersExported = 0;
            mstrCurrentOperation = string.Format("initializing export of {0}", strPSTFilename);
            OnExecutionProgress(new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Log, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), null));
            mstrExportFolder = strExportFolder;
            mstrPSTFilename = strPSTFilename;
            mblnWriteAttachmentBinary = blnWriteAttachmentBinary;
            mblnWriteMessageBinary = blnWriteMessageBinary;
            mblnNewExport = true;

            Application olApplication = new Application();
            try
            {
                mstrCurrentOperation = string.Format("log in to outlook profile \"{0}\"", strProfile);
                olApplication.Session.Logon(strProfile, "", false, true);
                molNamespace = olApplication.Session;
                mstrCurrentOperation = string.Format("add {0} to outlook profile \"{1}\"", mstrPSTFilename, strProfile);
                molNamespace.AddStore(mstrPSTFilename);
                Stores olStores = molNamespace.Stores;
                bool blnStoreFound = false;
                foreach (Store olStore in olStores)
                {
                    if (olStore.FilePath.ToLower() == mstrPSTFilename.ToLower())
                    {
                        blnStoreFound = true;
                        mstrCurrentOperation = string.Format("find root folder in {0}", mstrPSTFilename);
                        molRootFolder = olStore.GetRootFolder();
                        mintItemsCount = 1;
                        mstrCurrentOperation = string.Format("establish asynchronous thread");
                        Guid gTask = InitializeAsync();
                        WorkerEventHandler wehHandler = new WorkerEventHandler(EnumerateFolders);
                        wehHandler.BeginInvoke(molRootFolder, (AsyncOperation)mhdStateDictionary[gTask], new AsyncCallback(ExecuteCallback), gTask);
                    }
                }
                if (!blnStoreFound)
                {
                    mstrCurrentOperation = string.Format("find store {0} in outlook profile \"{1}\"", mstrPSTFilename, strProfile);
                    throw new System.Exception(string.Format("File {0} not found", mstrPSTFilename));
                }
            }
            catch (System.Exception eException)
            {
                OnExecutionException(new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Exception, string.Format("Error:  Execution failure {0} as a result of {1}", mstrCurrentOperation, eException.Message), ((mintItemsProcessed * 100) / mintItemsCount), null));
                if (mhdStateDictionary.Count > 0)
                {
                    Cancel();
                }
                else
                {
                    if (molNamespace != null)
                    {
                        molNamespace.RemoveStore(molRootFolder);
                        molNamespace.Logoff();
                    }
                    mswTime.Stop();
                    OnExecutionComplete(new CompleteEventArgs(mintMessagesExported, mintFoldersExported, LogEntryType.Exception, string.Format("Execution aborted by exception while {0}", mstrCurrentOperation), mswTime.Elapsed, null, false, null));
                }
            }
        }

        /// <summary>
        /// Cancels the execution of a plug-in
        /// </summary>
        /// <returns>void</returns>
        public void Cancel()
        {
            if (mhdStateDictionary.Count > 0)
            {
                foreach (DictionaryEntry deStateEntry in mhdStateDictionary)
                {
                    CancelAsync(deStateEntry.Key);
                }
            }
        }

        #endregion iPlugMethods

        // This method cancels a pending asynchronous operation.
        public void CancelAsync(object gTask)
        {
            AsyncOperation aoOperation = (AsyncOperation)mhdStateDictionary[gTask];
            if (aoOperation != null)
            {
                lock (mhdStateDictionary.SyncRoot)
                {
                    mhdStateDictionary.Remove(gTask);
                }
            }
        }

        #endregion Public Methods

        /////////////////////////////////////////////////////////////
        #region Private methods

        private void ExecuteCallback(IAsyncResult iarResult)
        {
            Guid gTask = (Guid)iarResult.AsyncState;
            AsyncOperation aoOperation = (AsyncOperation)mhdStateDictionary[gTask];
            bool blnAbort = false;
            if (aoOperation != null)
            {
                lock (mhdStateDictionary.SyncRoot)
                {
                    mhdStateDictionary.Remove(gTask);
                }
            }
            else
            {
                blnAbort = true;
            }
            if (molNamespace != null)
            {
                molNamespace.RemoveStore(molRootFolder);
                molNamespace.Logoff();

                ((Microsoft.Office.Interop.Outlook._Application)molNamespace.Application).Quit();
                molNamespace = null;
            }
            mswTime.Stop();
            aoOperation.PostOperationCompleted(this.PostComplete, new CompleteEventArgs(mintItemsProcessed, 0, LogEntryType.Log, "Completed Status Message needs work", mswTime.Elapsed, null, false, null));
        }

        private void EnumerateFolders(MAPIFolder olFolder, AsyncOperation aoOperation)
        {
            bool blnNewFolder = true;
            string strExportFolder = "";
            MailItem omiItem;

            if (!TaskCanceled(aoOperation.UserSuppliedState))
            {
                foreach (object oItem in olFolder.Items)
                {
                    try
                    {
                        mstrCurrentOperation = string.Format("check asynchronous cancellation on before examining item {0} in folder {1}", mintTaskItemsProcessed + 1, olFolder.FullFolderPath);
                        if (!TaskCanceled(aoOperation.UserSuppliedState))
                        {
                            if (oItem is MailItem)
                            {
                                omiItem = (MailItem)oItem;
                                if (mblnNewExport)
                                {
                                    mstrCurrentOperation = string.Format("parse export folder {0}", mstrExportFolder);
                                    DirectoryInfo diDirectory = new DirectoryInfo(mstrExportFolder);
                                    mstrCurrentOperation = string.Format("check export folder {0} existence", mstrExportFolder);
                                    if (!diDirectory.Exists)
                                    {
                                        mstrCurrentOperation = string.Format("create export folder {0}", mstrExportFolder);
                                        diDirectory.Create();
                                    }
                                    mblnNewExport = false;
                                }
                                if (blnNewFolder)
                                {
                                    mstrCurrentOperation = string.Format("parse export folder {0}", mstrExportFolder);
                                    int intRoot = olFolder.FullFolderPath.IndexOf("\\\\");
                                    intRoot = intRoot < 0 ? intRoot : intRoot + 2;
                                    int intStart = olFolder.FullFolderPath.IndexOf("\\", intRoot);
                                    intStart = intStart < 0 ? 0 : intStart;
                                    strExportFolder = string.Format("{0}{1}{2}", mstrExportFolder, (intStart == 0 ? "\\" : ""), olFolder.FullFolderPath.Substring(intStart, olFolder.FullFolderPath.Length - intStart));
                                    DirectoryInfo diDirectory = new DirectoryInfo(strExportFolder);
                                    mstrCurrentOperation = string.Format("check export folder {0} existence", strExportFolder);
                                    if (!diDirectory.Exists)
                                    {
                                        mstrCurrentOperation = string.Format("create export folder {0}", mstrExportFolder);
                                        diDirectory.Create();
                                    }
                                    blnNewFolder = false;
                                    mintFoldersExported++;
                                }
                                mstrCurrentOperation = string.Format("check asynchronous cancellation on before processing item {0} in folder {1}", mintTaskItemsProcessed + 1, olFolder.FullFolderPath);
                                mintTaskItemsCount = olFolder.Items.Count;
                                if (!TaskCanceled(aoOperation.UserSuppliedState))
                                {
                                    mstrCurrentOperation = string.Format("process item {0} in folder {1}", mintTaskItemsProcessed + 1, olFolder.FullFolderPath);
                                    ProcessItem(omiItem, strExportFolder, aoOperation);
                                    mintTaskItemsProcessed++;

                                    mstrCurrentOperation = string.Format("update status after processing item {0} in folder {1}", mintTaskItemsProcessed, olFolder.FullFolderPath);
                                    bool blnUpdate = (mblnWriteAttachmentBinary && mblnWriteMessageBinary) ? true : (mintItemsProcessed % 5 == 0);

                                    if (blnUpdate)
                                    {
                                        aoOperation.Post(this.PostProgress, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Debug, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                                    }
                                }
                            }
                        }
                    }
                    catch (System.Exception eException)
                    {
                        aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Exception, string.Format("Error:  Execution failure {0} as a result of {1}", mstrCurrentOperation, eException.Message), ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                    }
                }

                if (olFolder.Folders.Count > 0)
                {
                    try
                    {
                        mstrCurrentOperation = string.Format("check asynchronous cancellation on before examining subfolders under folder {0}", olFolder.FullFolderPath);
                        if (!TaskCanceled(aoOperation.UserSuppliedState))
                        {

                            mintItemsCount += olFolder.Folders.Count;
                            foreach (MAPIFolder olChildFolder in olFolder.Folders)
                            {
                                mstrCurrentOperation = string.Format("process subfolder {0}", olChildFolder.FullFolderPath);
                                EnumerateFolders(olChildFolder, aoOperation);
                            }
                        }
                    }
                    catch (System.Exception eException)
                    {
                        aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Exception, string.Format("Error:  Execution failure {0} as a result of {1}", mstrCurrentOperation, eException.Message), ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                    }
                }
                try
                {
                    mstrCurrentOperation = string.Format("check asynchronous cancellation on before updating status after processing folder {0}", mintTaskItemsProcessed + 1, olFolder.FullFolderPath);
                    if (!TaskCanceled(aoOperation.UserSuppliedState))
                    {
                        mstrCurrentOperation = string.Format("update status after processing folder {0}", mintTaskItemsProcessed + 1, olFolder.FullFolderPath);
                        mintItemsProcessed++;
                        mintFoldersExported++;
                        aoOperation.Post(this.PostProgress, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Debug, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                    }
                }
                catch (System.Exception eException)
                {
                    aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Exception, string.Format("Error:  Execution failure {0} as a result of {1}", mstrCurrentOperation, eException.Message), ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                }
            }
        }

        private void ProcessItem(MailItem omiItem, string strExportFolder, AsyncOperation aoOperation)
        {
            bool blnFileNameError = false;
            bool blnFileNoNameError = false;
            bool blnMessageException = false;
            int intLoc = 0;
            int intAttachments = 0;
            string mstrCurrentOperation = "";
            string strExportFile = "";
            string strExportFileSpec = "";
            string strTempFile = ""; 
            string strAttachmentFile = "";
            string strDuplicate = "";
            Attach miaAttachment;
            FileInfo fiFile;
            Message mItem;
            List<NVP> lmidItemDates;
            List<NVP> lmirRecipients;
            List<NVP> lmciConversationIDs;
            List<Attach> lmiaAttachments = new List<Attach>();
            NVP midItemDate;
            NVP mirRecipient;
            NVP mciConversationID;
            PropertyAccessor oliPA;
            PropertyAccessor olaPA;
            try
            {
                mstrCurrentOperation = string.Format("create export message object");
                mItem = new Message();
                mItem.EngineVersion = Description;
                mstrCurrentOperation = string.Format("create export message date objects");
                lmidItemDates = new List<NVP>();
                midItemDate = new NVP();
                mstrCurrentOperation = string.Format("access message date received (initial MailItem object access)");
                try
                {
                    if (omiItem.ReceivedTime != null)
                    {
                        mstrCurrentOperation = string.Format("parse export message date received");
                        midItemDate.Type = "Received";
                        midItemDate.Name = String.Format("{0:MM-dd-yyyy hh:mm:ss tt}", omiItem.ReceivedTime);
                        mItem.Received = omiItem.ReceivedTime;
                        mstrCurrentOperation = string.Format("add export message date received to dates list on {0} in {1}", mItem.Filespec, strExportFolder);
                        lmidItemDates.Add(midItemDate);
                    }
                    else
                    {
                        mstrCurrentOperation = string.Format("Warning:  Unable to {0} as a result of a null ReceivedTime property on the MailItem object", mstrCurrentOperation);
                        aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                        mItem.Received = new DateTime();
                    }
                }
                catch (System.Exception eException)
                {
                    mstrCurrentOperation = string.Format("Error:  Unable to {0} on item {1} of {2} in {3} (total items written {4}) as a result of {5}", mstrCurrentOperation, mintTaskItemsProcessed + 1, mintTaskItemsCount, strExportFolder, mintItemsProcessed, eException.Message);
                    aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Exception, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                    mItem.Received = new DateTime();
                    blnMessageException = true;
                }
                mstrCurrentOperation = string.Format("create export message date object on {0} in {1}", mItem.Filespec, strExportFolder);
                if (omiItem.SentOn != null)
                {
                    midItemDate = new NVP();
                    mstrCurrentOperation = string.Format("parse export message date sent on {0} in {1}", mItem.Filespec, strExportFolder);
                    midItemDate.Type = "Sent";
                    midItemDate.Name = String.Format("{0:MM-dd-yyyy hh:mm:ss tt}", omiItem.SentOn);
                    mstrCurrentOperation = string.Format("add export message date sent to dates list on {0} in {1}", mItem.Filespec, strExportFolder);
                    lmidItemDates.Add(midItemDate);
                }
                else
                {
                    mstrCurrentOperation = string.Format("Warning:  Unable to {0} as a result of a null SentOn property on the MailItem object", mstrCurrentOperation);
                    aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                }

                mstrCurrentOperation = string.Format("add export message dates list to message object on {0} in {1}", mItem.Filespec, strExportFolder);
                mItem.ItemDates = lmidItemDates;
                mstrCurrentOperation = string.Format("create export message recipient objects on {0} in {1}", mItem.Filespec, strExportFolder);
                lmirRecipients = new List<NVP>();
                mirRecipient = new NVP();
                mstrCurrentOperation = string.Format("parse export message sender name on {0} in {1}", mItem.Filespec, strExportFolder);
                if (omiItem.SenderName != null)
                {
                    intLoc = omiItem.SenderName.IndexOf(",") > 0 ? 0 : omiItem.SenderName.LastIndexOf(" ");
                    if (intLoc > 0)
                    {
                        mirRecipient.Name = omiItem.SenderName.Substring(intLoc + 1) + ", " + omiItem.SenderName.Substring(0, intLoc);
                    }
                    else
                    {
                        mirRecipient.Name = omiItem.SenderName;
                    }
                    mirRecipient.Type = "Sender";
                    mstrCurrentOperation = string.Format("add export message sender name to recipients list on {0} in {1}", mItem.Filespec, strExportFolder);
                    lmirRecipients.Add(mirRecipient);
                }
                else
                {
                    mstrCurrentOperation = string.Format("Warning:  Unable to {0} as a result of a null SenderName property in the MailItem object", mstrCurrentOperation);
                    aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                }
                mstrCurrentOperation = string.Format("check export message recipients list on {0} in {1}", mItem.Filespec, strExportFolder);
                foreach (Recipient olrRecipient in omiItem.Recipients)
                {
                    mstrCurrentOperation = string.Format("create export message recipient object on {0} in {1}", mItem.Filespec, strExportFolder);
                    mirRecipient = new NVP();
                    mstrCurrentOperation = string.Format("parse export message recipient name on {0} in {1}", mItem.Filespec, strExportFolder);
                    if (olrRecipient.Name != null)
                    {
                        intLoc = olrRecipient.Name.IndexOf(",") > 0 ? 0 : olrRecipient.Name.LastIndexOf(" ");
                        if (intLoc > 0)
                        {
                            mirRecipient.Name = olrRecipient.Name.Substring(intLoc + 1) + ", " + olrRecipient.Name.Substring(0, intLoc);
                        }
                        else
                        {
                            mirRecipient.Name = olrRecipient.Name;
                        }
                        mstrCurrentOperation = string.Format("determine export message recipient type on {0} in {1}", mItem.Filespec, strExportFolder);
                        switch (olrRecipient.Type)
                        {
                            case (int)OlMailRecipientType.olBCC:
                                mirRecipient.Type = "BCC";
                                break;
                            case (int)OlMailRecipientType.olCC:
                                mirRecipient.Type = "CC";
                                break;
                            case (int)OlMailRecipientType.olOriginator:
                                mirRecipient.Type = "Originator";
                                break;
                            case (int)OlMailRecipientType.olTo:
                                mirRecipient.Type = "To";
                                break;
                            default:
                                mirRecipient.Type = "Unknown";
                                break;
                        }
                        mstrCurrentOperation = string.Format("add export message recipient name to recipients list on {0} in {1}", mItem.Filespec, strExportFolder);
                        lmirRecipients.Add(mirRecipient);
                    }
                    else
                    {
                        mstrCurrentOperation = string.Format("Warning:  Unable to {0} as a result of a null Name property in a Recipient object in the Recipients list on the MailItem object", mstrCurrentOperation);
                        aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                    }
                }
                mstrCurrentOperation = string.Format("add export message recipients list to message object on {0} in {1}", mItem.Filespec, strExportFolder);
                mItem.Recipients = lmirRecipients;
                mstrCurrentOperation = string.Format("add export message subject to message object on {0} in {1}", mItem.Filespec, strExportFolder);
                if (omiItem.Subject != null)
                {
                    mItem.Subject = omiItem.Subject;
                }
                else
                {
                    mstrCurrentOperation = string.Format("Warning:  Unable to {0} as a result of a null Subject property on the MailItem object", mstrCurrentOperation);
                    aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                }
                mstrCurrentOperation = string.Format("determine export message body format and add export message body to message object on {0} in {1}", mItem.Filespec, strExportFolder);
                switch (omiItem.BodyFormat)
                {
                    case OlBodyFormat.olFormatHTML:
                        mItem.BodyType = "HTML";
                        if (omiItem.HTMLBody != null)
                        {
                            mItem.Body = omiItem.HTMLBody;
                        }
                        else
                        {
                            mstrCurrentOperation = string.Format("Warning:  Unable to {0} as a result of a null HTMLBody property on the MailItem object", mstrCurrentOperation);
                            aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                        }
                        break;
                    case OlBodyFormat.olFormatPlain:
                        mItem.BodyType = "Plain";
                        if (omiItem.Body != null)
                        {
                            mItem.Body = omiItem.Body;
                        }
                        else
                        {
                            mstrCurrentOperation = string.Format("Warning:  Unable to {0} as a result of a null Body property on the MailItem object", mstrCurrentOperation);
                            aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                        }
                        break;
                    case OlBodyFormat.olFormatRichText:
                        mItem.BodyType = "RichText";
                        if (omiItem.HTMLBody != null)
                        {
                            mItem.Body = omiItem.HTMLBody;
                        }
                        else
                        {
                            mstrCurrentOperation = string.Format("Warning:  Unable to {0} as a result of a null HTMLBody property on the MailItem object", mstrCurrentOperation);
                            aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                        }
                        break;
                    case OlBodyFormat.olFormatUnspecified:
                        mItem.BodyType = "Unspecified"; if (omiItem.Body != null)
                        {
                            mItem.Body = omiItem.Body;
                        }
                        else
                        {
                            mstrCurrentOperation = string.Format("Warning:  Unable to {0} as a result of a null Body property on the MailItem object", mstrCurrentOperation);
                            aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                        }
                        break;
                }
                mstrCurrentOperation = string.Format("add export message plain text body to message object on {0} in {1}", mItem.Filespec, strExportFolder);
                if (omiItem.Body != null)
                {
                    mItem.PlainText = omiItem.Body;
                }
                else
                {
                    mstrCurrentOperation = string.Format("Warning:  Unable to {0} as a result of a null Body property on the MailItem object", mstrCurrentOperation);
                    aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                }
                mstrCurrentOperation = string.Format("add export message size to message object on {0} in {1}", mItem.Filespec, strExportFolder);
                mItem.Size = omiItem.Size;
                oliPA = omiItem.PropertyAccessor;
                try
                {
                    mItem.Header = (string)oliPA.GetProperty(PR_TRANSPORT_MESSAGE_HEADERS);
                }
                catch (System.Exception eException)
                {
                    mstrCurrentOperation = string.Format("Warning:  Unable to retrieve transport message headers on {0} in {1} as a result of {2}", mItem.Filespec, strExportFolder, eException.Message);
                    aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                }
                mstrCurrentOperation = string.Format("parse export message conversation/threading information on {0} in {1}", mItem.Filespec, strExportFolder);
                lmciConversationIDs = new List<NVP>();
                if (omiItem.ConversationIndex != null)
                {
                    mciConversationID = new NVP();
                    mciConversationID.Type = "ThreadID";
                    mciConversationID.Name = omiItem.ConversationIndex.Substring(0, 44);
                    lmciConversationIDs.Add(mciConversationID);
                    mciConversationID = new NVP();
                    mciConversationID.Type = "SubThreadID";
                    mciConversationID.Name = omiItem.ConversationIndex.Substring(44);
                    lmciConversationIDs.Add(mciConversationID);
                }
                else
                {
                    mstrCurrentOperation = string.Format("Warning:  Unable to {0} as a result of a null ConversationIndex property on the MailItem object", mstrCurrentOperation);
                    aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                }
                mItem.ConversationIDs = lmciConversationIDs;
                int intChar = 96;
                mstrCurrentOperation = string.Format("parse export message temporary filename on {0} in {1}", mItem.Filespec, strExportFolder);
                do
                {
                    intChar++;
                    strExportFileSpec = string.Format("{0}\\{1}{2}", strExportFolder, mItem.Filespec, Convert.ToChar(intChar));
                    strExportFile = string.Format("{0}.xml", strExportFileSpec);
                    fiFile = new FileInfo(strExportFile);
                } while (fiFile.Exists);
                if (mblnWriteMessageBinary)
                {
                    strTempFile = string.Format("{0}\\temp.msg", mstrExportFolder);
                    mstrCurrentOperation = string.Format("write export message temporary file {0} for {1} in {2}", strTempFile, mItem.Filespec, strExportFolder);
                    omiItem.SaveAs(strTempFile, OlSaveAsType.olMSG);

                    mstrCurrentOperation = string.Format("read export message temporary binary file {0} to message object on {1} in {2}", strTempFile, mItem.Filespec, strExportFolder);
                    mItem.OrigMessage = ReadBinaryFile(strTempFile);
                    mstrCurrentOperation = string.Format("delete export message temporary file {0} for {1} in {2}", strTempFile, mItem.Filespec, strExportFolder);
                    fiFile = new FileInfo(strTempFile);
                    if (fiFile.Exists) fiFile.Delete();
                }
                mstrCurrentOperation = string.Format("count export message attachments on {0} in {1}", mItem.Filespec, strExportFolder);
                if (omiItem.Attachments != null)
                {
                    if (omiItem.Attachments.Count > 0)
                    {
                        mstrCurrentOperation = string.Format("create export message attachment list on {0} in {1}", mItem.Filespec, strExportFolder);
                        intAttachments = 0;
                        blnFileNameError = false;
                        blnFileNoNameError = false;
                        foreach (Attachment oaAttachment in omiItem.Attachments)
                        {
                            intAttachments++;
                            mstrCurrentOperation = string.Format("create export message attachment object on {0} in {1}", mItem.Filespec, strExportFolder);
                            miaAttachment = new Attach();
                            mstrCurrentOperation = string.Format("parse export message attachment filename on {0} in {1}", mItem.Filespec, strExportFolder);
                            miaAttachment.FileIdentifier = string.Format("{0}", intAttachments);
                            strAttachmentFile = "";
                            strDuplicate = "";
                            intChar = 0;
                            do
                            {
                                intChar++;
                                strDuplicate = intChar > 1 ? string.Format("({0})-", intChar) : "";
                                mstrCurrentOperation = string.Format("access export message attachment filename on {0} in {1}", mItem.Filespec, strExportFolder);
                                try
                                {
                                    strAttachmentFile = string.Format("{0}-{1}{2}", strExportFileSpec, strDuplicate, ReplaceForbiddenCharacter(oaAttachment.FileName));
                                }
                                catch (System.Exception eException)
                                {
                                    try
                                    {
                                        strAttachmentFile = string.Format("{0}-{1}{2}({3})", strExportFileSpec, strDuplicate, ReplaceForbiddenCharacter(oaAttachment.DisplayName), oaAttachment.Index);
                                    }
                                    catch (System.Exception eException1)
                                    {
                                        strAttachmentFile = string.Format("{0}-{1}UnknownAttachment({2})", strExportFileSpec, strDuplicate, oaAttachment.Index);
                                        blnFileNoNameError = true;
                                    }
                                    blnFileNameError = true;
                                }
                                fiFile = new FileInfo(strAttachmentFile);
                            } while (fiFile.Exists);
                            mstrCurrentOperation = string.Format("add export message attachment file name {0} to attachment object on {1} in {2}", strAttachmentFile, mItem.Filespec, strExportFolder);
                            miaAttachment.Path = strAttachmentFile;
                            miaAttachment.Filename = new NZMEFilename();
                            miaAttachment.Filename.Name = ReplaceForbiddenCharacter(!blnFileNameError ? oaAttachment.FileName : !blnFileNoNameError ? string.Format("{0}({1})", oaAttachment.DisplayName, oaAttachment.Index) : string.Format("UnknownAttachment({0})", oaAttachment.Index));
                            olaPA = oaAttachment.PropertyAccessor;
                            try
                            {
                                miaAttachment.Filename.Extension = (string)olaPA.GetProperty(PR_ATTACH_EXTENSION);
                            }
                            catch (System.Exception eException)
                            {
                                mstrCurrentOperation = string.Format("Warning:  Unable to retrieve attachment extension on {0} in {1} as a result of {2}", strAttachmentFile, strExportFolder, eException.Message);
                                aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                            }
                            mstrCurrentOperation = string.Format("add export message attachment file {0} size to attachment object on {1} on {2}", strAttachmentFile, mItem.Filespec, strExportFolder);
                            miaAttachment.Filesize = oaAttachment.Size;
                            mstrCurrentOperation = string.Format("add export message attachment file {0} date and time to attachment object on {1} on {2}", strAttachmentFile, mItem.Filespec, strExportFolder);
                            miaAttachment.FileDateTime = new NZMEFileDateTime();
                            miaAttachment.FileDateTime.NZMEDate = new NZMEFileDate();
                            miaAttachment.FileDateTime.NZMETime = new NZMEFileTime();
                            //DateTime datCreationTime = new DateTime();
                            DateTime datModificationTime = new DateTime();
                            //try
                            //{
                            //    datCreationTime = (DateTime)olaPA.GetProperty(PR_CREATION_TIME);
                            //}
                            //catch (System.Exception ex)
                            //{
                            //    //nfnFilename.Extension = "Warning:  " + ex.Message;
                            //}
                            try
                            {
                                datModificationTime = (DateTime)olaPA.GetProperty(PR_LAST_MODIFICATION_TIME);
                            }
                            catch (System.Exception eException)
                            {
                                mstrCurrentOperation = string.Format("Warning:  Unable to retrieve attachment last modification time on {0} as a result of {1}", strAttachmentFile, eException.Message);
                                aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                            }
                            miaAttachment.FileDateTime.NZMEDate.NZMEDate = string.Format("{0:yyyyMMdd}", datModificationTime);
                            miaAttachment.FileDateTime.NZMETime.NZMETime = string.Format("{0:HHmmssfff}", datModificationTime);
                            try
                            {
                                miaAttachment.MimeTag = (string)olaPA.GetProperty(PR_ATTACH_MIME_TAG);
                            }
                            catch (System.Exception eException)
                            {
                                mstrCurrentOperation = string.Format("Warning:  Unable to retrieve attachment mime tag on {0} as a result of {1}", strAttachmentFile, eException.Message);
                                aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                            }
                            mstrCurrentOperation = string.Format("add export message attachment file {0} file format to attachment object on {1} in {2}", strAttachmentFile, mItem.Filespec, strExportFolder);
                            miaAttachment.FileFormat = new NZMEFileFormat();
                            miaAttachment.FileFormat.Format = "";
                            miaAttachment.FileFormat.Version = "";
                            mstrCurrentOperation = string.Format("add export message attachment file {0} text information to attachment object on {1} in {2}", strAttachmentFile, mItem.Filespec, strExportFolder);
                            miaAttachment.Text = new NZMEText();
                            miaAttachment.Text.CharacterSet = "";
                            miaAttachment.Text.MarkupLanguage = "";
                            mstrCurrentOperation = string.Format("write export message attachment file {0} for {1} in {2}", strAttachmentFile, mItem.Filespec, strExportFolder);
                            oaAttachment.SaveAsFile(strAttachmentFile);
                            if (mblnWriteAttachmentBinary)
                            {
                                mstrCurrentOperation = string.Format("read export message attachment binary file {0} to attachment object on {1} in {2}", strAttachmentFile, mItem.Filespec, strExportFolder);
                                miaAttachment.OrigFile = ReadBinaryFile(strAttachmentFile);
                            }
                            mstrCurrentOperation = string.Format("add export message attachment object to attachment list on {0} in {1}", mItem.Filespec, strExportFolder);
                            lmiaAttachments.Add(miaAttachment);
                            blnFileNameError = false;
                        }
                        mstrCurrentOperation = string.Format("add export message attachment list to message object on {0} in {1}", mItem.Filespec, strExportFolder);
                        mItem.Attachments = lmiaAttachments;
                    }
                }
                else
                {
                    mstrCurrentOperation = string.Format("Warning:  Unable to {0} as a result of a null Attachments collection on the MailItem object", mstrCurrentOperation);
                    aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                } 
                mstrCurrentOperation = string.Format("serialize export message object {0} to file {1}", mItem.Filespec, strExportFile);
                SerializeObject(mItem, strExportFile);
                mstrCurrentOperation = string.Format("update status after processing message {0} in {1}", mItem.Filespec, strExportFolder);
                mintItemsProcessed++;
                mstrCurrentOperation = string.Format("clearing objects after processing message {0} in {1}", mItem.Filespec, strExportFolder);
                miaAttachment = null;
                lmiaAttachments.Clear();
                lmiaAttachments = null;
                fiFile = null;
                mItem = null;
                lmidItemDates.Clear();
                lmidItemDates = null;
                lmirRecipients.Clear();
                lmirRecipients = null;
                lmciConversationIDs.Clear();
                lmciConversationIDs = null;
                midItemDate = null;
                mirRecipient = null;
                mciConversationID = null;
                oliPA = null;
                olaPA = null;
            }
            catch (System.Exception eException)
            {
                if (blnMessageException)
                {
                    mstrCurrentOperation = string.Format("Error:  Message Export Failure, Message unusable, item {0} of {1} in {2} (total items written {3}) as a result of {4}", mintTaskItemsProcessed + 1, mintTaskItemsCount, strExportFolder, mintItemsProcessed, eException.Message);
                    aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                }
                else
                {
                    mstrCurrentOperation = string.Format("Error:  Message Export Failure, Unable to {0} on item {1} of {2} in {3} (total items written {4}) as a result of {5}", mstrCurrentOperation, mintTaskItemsProcessed + 1, mintTaskItemsCount, strExportFolder, mintItemsProcessed, eException.Message);
                    aoOperation.Post(this.PostException, new ProgressEventArgs(((mintTaskItemsProcessed * 100) / mintTaskItemsCount), ((mintItemsProcessed * 100) / mintItemsCount), mintMessagesExported, mintFoldersExported, LogEntryType.Warning, mstrCurrentOperation, ((mintItemsProcessed * 100) / mintItemsCount), aoOperation.UserSuppliedState));
                }
            }
        }

        private byte[] ReadBinaryFile(string strFilename)
        {
            string strExceptionOperation = "";
            FileStream fsStream = new FileStream(strFilename, FileMode.Open);
            MemoryStream msStream = new MemoryStream();
            try
            {
                strExceptionOperation = string.Format("creating binary reader object for file {0}", strFilename);
                BinaryReader brReader = new BinaryReader(fsStream);
                strExceptionOperation = string.Format("creating binary read buffer for file {0}", strFilename);
                byte[] baBuffer = new byte[50];
                int intReadBytes = 0;

                strExceptionOperation = string.Format("reading binary information into read buffer for file {0}", strFilename);
                while ((intReadBytes = brReader.Read(baBuffer, 0, 50)) > 0)
                {
                    strExceptionOperation = string.Format("writing binary information into output memory stream for file {0}", strFilename);
                    msStream.Write(baBuffer, 0, intReadBytes);
                }
            }
            catch (System.Exception eException)
            {
                throw new System.Exception(string.Format("Error:  Unable to {0} as a result of {1}", strExceptionOperation, eException.Message));
            }
            finally
            {
                fsStream.Close();
                fsStream.Dispose();
            }
            return msStream.ToArray();
        }

        private void SerializeObject(Message mItem, string strFilename)
        {
            XmlSerializer xsSerializer = new XmlSerializer(typeof(Message));
            StreamWriter swWriter = new StreamWriter(strFilename);

            xsSerializer.Serialize(swWriter, mItem);
            swWriter.Close();
        }

        private Guid InitializeAsync()
        {
            Guid gTask = Guid.NewGuid();
            AsyncOperation aoOperation = AsyncOperationManager.CreateOperation(gTask);

            // Multiple threads will access the task dictionary,
            // so it must be locked to serialize access.
            lock (mhdStateDictionary.SyncRoot)
            {
                if (mhdStateDictionary.Contains(gTask))
                {
                    throw new ArgumentException("Task ID parameter must be unique", "gTask");
                }

                mhdStateDictionary[gTask] = aoOperation;
            }
            return gTask;
        }

        private bool TaskCanceled(object gTask)
        {
            return (mhdStateDictionary[gTask] == null);
        }

        private string ReplaceForbiddenCharacter(string strFile)
        {
            strFile = strFile.Replace("/", "&#x2F;");
            strFile = strFile.Replace("\\", "&#x5C;");
            strFile = strFile.Replace(":", "&#x3A;");
            strFile = strFile.Replace("*", "&#x2A;");
            strFile = strFile.Replace("?", "&#x3F;");
            strFile = strFile.Replace("\"", "&#x22;");
            strFile = strFile.Replace("<", "&#x3C;");
            strFile = strFile.Replace(">", "&#x3E;");
            strFile = strFile.Replace("|", "&#x7C;");
            strFile = strFile.Replace("'", "&#x27;");
            strFile = strFile.Trim();
            return strFile;
        }

        //private void TestMethod()
        //{
        //    SuperPackage spPackage = new SuperPackage();
        //}

        #endregion Private Methods
    }
}
